<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script async src="https://unpkg.com/es-module-shims@1.8.0/dist/es-module-shims.js"></script>
    <script type="importmap">
      {
        "imports": {
          "three": "https://unpkg.com/three@0.156.0/build/three.module.js"
        }
      }
    </script>
  </head>
  <body style="margin: 0">
    <script type="module">
      import * as THREE from 'three'

      const scene = new THREE.Scene()

      const geometry = new THREE.CylinderGeometry(500, 500, 500 * 2 * Math.PI / 13328 * 3136, 60, 1, true)
      geometry.scale(-1, 1, 1)

      const texture = new THREE.TextureLoader().load('panorama.jpg')
      texture.colorSpace = THREE.SRGBColorSpace

      const material = new THREE.MeshBasicMaterial({ map: texture })

      const mesh = new THREE.Mesh(geometry, material)
      scene.add(mesh)

      const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
      let camYaw = 0, camPitch = 0
      camera.setRotationFromEuler(new THREE.Euler(camPitch, camYaw, 0, 'YXZ'))

      const renderer = new THREE.WebGLRenderer()
      renderer.setSize(window.innerWidth, window.innerHeight)
      document.body.appendChild(renderer.domElement)

      window.onresize = () => {
        camera.aspect = window.innerWidth / window.innerHeight
        camera.updateProjectionMatrix()

        renderer.setSize(window.innerWidth, window.innerHeight)
      }

      window.onmousedown = e => {
        let last = e
        window.onmousemove = e => {
          const PITCH_MAX = Math.PI / 2 - 0.01
          camYaw += (e.clientX - last.clientX) * 0.002 / camera.zoom
          camPitch += (e.clientY - last.clientY) * 0.002 / camera.zoom
          if (camPitch > PITCH_MAX) camPitch = PITCH_MAX
          if (camPitch < -PITCH_MAX) camPitch = -PITCH_MAX
          last = e
        }

        window.onmouseup = () => {
          window.onmousemove = null
          window.onmouseup = null
        }
      }

      window.onwheel = e => {
        camera.zoom -= e.deltaY * 0.001
        if (camera.zoom > 5) camera.zoom = 5
        if (camera.zoom < 1) camera.zoom = 1
        camera.updateProjectionMatrix()
      }

      function animate() {
        requestAnimationFrame(animate)
        camera.setRotationFromEuler(new THREE.Euler(camPitch, camYaw, 0, 'YXZ'))
        renderer.render(scene, camera)
      }

      animate()
    </script>
  </body>
</html>
